package zpe.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import zpe.controledeacesso.model.bean.Localidade;
import zpe.controledeacesso.model.bean.NivelAcesso;
import zpe.genericcrud.model.Entidade;

@Entity
@Table(name = "tb_cliente", schema = "dbo")
public class Cliente implements Entidade {

	private static final long serialVersionUID = 3176814900832143343L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ci_cliente")
	private Integer id;

	@Column(name = "nm_fantasia")
	private String descricao;
	
	@Column(name = "nm_razao_social")
	private String razaoSocial;
	
	@Column(name = "nr_cnpj")
	private String cnpj;
	
	@Column( name="fl_nivel_acesso", nullable = true )
	private NivelAcesso nivelDeAcesso = NivelAcesso.INDEFINIDO;
	
	@Column(name = "nr_insc_estadual")
	private String inscricaoEstadual;
	
	@Column(name = "nr_insc_municipal")
	private String inscricaoMunicipal;
	
	@Column(name = "nm_bairro")
	private String bairro;
	
	@Column(name = "nr_cep")
	private String cep;
	
	@Column(name = "ds_endereco")
	private String endereco;
	
	@Column(name = "nr_numero")
	private String numero;
	
	@OneToOne(fetch = FetchType.EAGER)
	@JoinColumn( name = "cd_municipio", nullable = false)
	private Localidade municipio = new Localidade();
	
	@Column(name = "ds_complemento")
	private String complemento;
	
	@Column(name = "nr_celular")
	private String celular;
	
	@Column(name = "nr_telefone")
	private String telefone;
	
	@Column(name = "nr_fax")
	private String fax;
	
	@Column(name = "ds_passaporte")
	private String passaporte;
	
	@Column(name = "fl_ativo")
	private Character ativo;
	
	@Column(name = "fl_cliente_antaq")
	private Character clienteAntaq;
	
	@Column(name = "dt_inicio")
	private Date dataInicio;
	
	@Column(name = "dt_fim")
	private Date dataFim;
	
	@Column(name = "fl_substituto_municipal")
	private Character substitutoMunicipal;
	
	@Column(name = "fl_substituto_estadual")
	private Character substitutoEstadual;
	
	@OneToMany(mappedBy = "cliente", targetEntity = ClienteEmail.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
	private List<ClienteEmail> emails = new ArrayList<ClienteEmail>();

	/*
	@ManyToMany( fetch = FetchType.LAZY )
	@JoinTable( name = "dbo.tb_cliente_usuarios", joinColumns = @JoinColumn ( name = "cd_usuario" ) ,inverseJoinColumns = @JoinColumn( name = "cd_cliente" ) )
	private List<Usuario> usuarios = new ArrayList<Usuario>();
	*/
	
	@OneToMany(mappedBy = "cliente", targetEntity = ClienteUsuario.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
	private List<ClienteUsuario> usuarios = new ArrayList<ClienteUsuario>();
	
	public Integer getId() {
		return id;
	}

	public List<ClienteEmail> getEmails() {
		return emails;
	}

	public void setEmails(List<ClienteEmail> emails) {
		this.emails = emails;
	}

	public Cliente(String nome, Integer id) {

		this.id = id;
		
		this.descricao = nome;
		
	}
	
	public Cliente() {}
	
	/**
	 * @return the descricao
	 */
	public String getDescricao() {
		return descricao;
	}

	public List<ClienteUsuario> getUsuarios() {
		return usuarios;
	}

	public void setUsuarios(List<ClienteUsuario> usuarios) {
		this.usuarios = usuarios;
	}

	/**
	 * @param descricao
	 *            the descricao to set
	 */
	public void setDescricao(String descricao) {
		if (descricao != null)
			descricao = descricao.toUpperCase();
		this.descricao = descricao;
	}

	public String getRazaoSocial() {
		return razaoSocial;
	}

	public void setRazaoSocial(String razaoSocial) {
		this.razaoSocial = razaoSocial;
	}

	public String getCnpj() {
		return cnpj;
	}

	public void setCnpj(String cnpj) {
		this.cnpj = cnpj.replaceAll("\\.","").replaceAll("\\/","").replace("-","");
	}

	public NivelAcesso getNivelDeAcesso() {
		return nivelDeAcesso;
	}

	public void setNivelDeAcesso(NivelAcesso nivelDeAcesso) {
		this.nivelDeAcesso = nivelDeAcesso;
	}

	public String getInscricaoEstadual() {
		return inscricaoEstadual;
	}

	public void setInscricaoEstadual(String inscricaoEstadual) {
		this.inscricaoEstadual = inscricaoEstadual;
	}

	public String getInscricaoMunicipal() {
		return inscricaoMunicipal;
	}

	public void setInscricaoMunicipal(String inscricaoMunicipal) {
		this.inscricaoMunicipal = inscricaoMunicipal;
	}

	public String getBairro() {
		return bairro;
	}

	public void setBairro(String bairro) {
		this.bairro = bairro;
	}

	public String getCep() {
		return cep;
	}

	public String getTelefone() {
		return telefone;
	}

	public void setTelefone(String telefone) {
		this.telefone = telefone;
	}

	public void setCep(String cep) {
		this.cep = cep;
	}

	public String getEndereco() {
		return endereco;
	}

	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}

	public String getNumero() {
		return numero;
	}

	public void setNumero(String numero) {
		this.numero = numero;
	}

	public Localidade getMunicipio() {
		return municipio;
	}

	public void setMunicipio(Localidade municipio) {
		this.municipio = municipio;
	}

	public String getComplemento() {
		return complemento;
	}
	
	public boolean isNivelMaster(){
		return this.nivelDeAcesso.equals( NivelAcesso.MASTER );
	}

	public void setComplemento(String complemento) {
		this.complemento = complemento;
	}

	public String getCelular() {
		return celular;
	}

	public void setCelular(String celular) {
		this.celular = celular;
	}

	public String getFax() {
		return fax;
	}

	public void setFax(String fax) {
		this.fax = fax;
	}

	public String getPassaporte() {
		return passaporte;
	}

	public void setPassaporte(String passaporte) {
		this.passaporte = passaporte;
	}

	public Character getAtivo() {
		return ativo;
	}

	public void setAtivo(Character ativo) {
		this.ativo = ativo;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}

	public static long getSerialVersionUID() {
		return serialVersionUID;
	}

	public Character getClienteAntaq() {
		return clienteAntaq;
	}

	public void setClienteAntaq(Character clienteAntaq) {
		this.clienteAntaq = clienteAntaq;
	}

	public Date getDataInicio() {
		return dataInicio;
	}

	public void setDataInicio(Date dataInicio) {
		this.dataInicio = dataInicio;
	}

	public Date getDataFim() {
		return dataFim;
	}

	public void setDataFim(Date dataFim) {
		this.dataFim = dataFim;
	}

	public Character getSubstitutoMunicipal() {
		return substitutoMunicipal;
	}

	public void setSubstitutoMunicipal(Character substitutoMunicipal) {
		this.substitutoMunicipal = substitutoMunicipal;
	}

	public Character getSubstitutoEstadual() {
		return substitutoEstadual;
	}

	public void setSubstitutoEstadual(Character substitutoEstadual) {
		this.substitutoEstadual = substitutoEstadual;
	}

	public boolean isEmpty() {
		return (id == null && (descricao == null || descricao.trim().isEmpty()));
	}

	public Map<String, Object> notEmptyFields() {
		Map<String, Object> map = new HashMap<String, Object>();
		if (descricao != null && !descricao.trim().isEmpty())
			map.put("descricao", descricao);
		return map;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cliente other = (Cliente) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return this.descricao;
	}

}
